<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #qrcodeCanvas {
            position: absolute;
            cursor: nw-resize;
            /* cursor: move; */
            background-image: url('');
            background-size: contain;
            opacity: 0.3;

            border: 2px solid rgba(0, 255, 0, 1);
            position: absolute;
            left: -2px;
            top: -2px;
            user-select: none;
        }
        #qrcodeCanvasInner{
            cursor: move;
        }
        img{
            pointer-events: none;
            user-select: none;
            position: relative;
            vertical-align: top;
            display: inline-block !important;
        }
        #draggableHandle {
            position: absolute;
            bottom: 0;
            right: 0;
            width: 20px;
            height: 20px;
            background-color: #ccc;
            opacity: 0.5;
        }
        #box{
            float: left;
            position: relative;
            border: 10px solid red;
            cursor: se-resize;
        }
        #backgroundCanvas{
            position: relative;
            cursor: default;
            width: 300px;
            height: 300px;
            vertical-align: top;
        }
    </style>
    <script src="https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
</head>
<body>
    <div>
        二维码文本：<input type="text" id="qrcodeText"><br>
        图片上传：<input type="file" id="imageInput" accept="image/*"><br>
        宽度：<input type="number" id="width"> 
        <button>绑定</button>
        高度：<input type="number" id="height">
        <button id="exportButton">导出图片</button>
    </div>
    <div id="box">
        <canvas id="backgroundCanvas"></canvas>
        <div id="qrcodeCanvas">
            <div id="qrcodeCanvasInner">

            </div>
        </div>
    </div>
    <div id="show">

    </div>

    <script>
        // 二维码对象
        var qrcode = null;

        // 图片预览和加载
        document.getElementById('imageInput').addEventListener('change', function(e) {
            var file = e.target.files[0];
            var reader = new FileReader();
            reader.onload = function(event) {
                var img = new Image();
                img.onload = function() {
                    var ctxBg = document.getElementById('backgroundCanvas').getContext('2d');
                    // 将背景画布大小设为图片大小
                    backgroundCanvas.width = img.width;
                    backgroundCanvas.height = img.height;
                    // backgroundCanvas.style.removeProperty("width")
                    // backgroundCanvas.style.removeProperty("height") 
                    backgroundCanvas.style.width = img.width+"px";
                    backgroundCanvas.style.height = img.height+"px";
                    console.log(backgroundCanvas)
                    // 绘制图片到背景画布
                    ctxBg.drawImage(img, 0, 0, img.width, img.height);
                    updateQrCode(qrcodeText.value);
                };
                img.src = event.target.result;
            };
            reader.readAsDataURL(file);
        });

        // 监听文本框变化
        document.getElementById('qrcodeText').addEventListener('input', function() {
            updateQrCode(this.value);
        });

        // 更新二维码
        function updateQrCode(text) {
            var div = document.getElementById("qrcodeCanvas");
            var backgroundCanvas = document.getElementById("backgroundCanvas");
            let maxValue = Math.min(backgroundCanvas.offsetWidth,backgroundCanvas.offsetHeight)
            let width = div.width;
            if (!qrcode) {
                qrcode = new QRCode(document.getElementById("qrcodeCanvasInner"), {
                    text: text,
                    width: maxValue>width&&width>0?width:maxValue>300?300:maxValue,
                    height: maxValue>width&&width>0?width:maxValue>300?300:maxValue,
                    colorDark : "#000",
                    colorLight : "#fff",
                    correctLevel : QRCode.CorrectLevel.H
                });
            } else {
                qrcode.clear();
                qrcode.makeCode(text);
            }
            // 启用内框拖拽功能
            enableDraggable2();
        }
        // 启用外框拖拽功能
        enableDraggable();

        // 启用外框拖拽功能
        function enableDraggable() {
            var backgroundCanvas = document.getElementById('backgroundCanvas');
            var qrcodeCanvas = document.getElementById('qrcodeCanvas');
            var qrcodeCanvasInner = document.getElementById("qrcodeCanvasInner");
            var box = document.getElementById('box');
            var startX, startY, endX, endY,originalW, originalH;
            backgroundCanvas.addEventListener('mousedown',function(e){
                e.stopPropagation();
            });
            box.addEventListener('mousedown', function(event) {
                startX = event.clientX;
                startY = event.clientY;
                originalW = backgroundCanvas.offsetWidth;
                originalH = backgroundCanvas.offsetHeight;
                document.addEventListener('mousemove', resizeCanvas);
                document.addEventListener('mouseup', stopResizeCanvas);
            });
            
            
            function resizeCanvas(event) {
                // 根据y轴线的变化等比获取x轴线变化值
                endX = event.clientX;
                endY = event.clientY;
                changeX = endX - startX;
                changeY = endY - startY;
                // 根据x值的变化来计算y值的变化
                var X1 = originalW+changeX;
                var Y2 = originalH+changeY;
                var Y1 = X1/originalW*originalH;
                var X2 = Y2/originalH*originalW;
                let x = Math.max(X1, X2);
                let y = x == X1 ? Y1 : Y2;
                if(x<(qrcodeCanvas.clientWidth+qrcodeCanvas.offsetLeft+2)){
                    x = qrcodeCanvas.clientWidth+qrcodeCanvas.offsetLeft+2;
                    y = x/originalW*originalH;
                }
                if(y<(qrcodeCanvas.clientHeight+qrcodeCanvas.offsetTop+2)){
                    y = qrcodeCanvas.clientHeight+qrcodeCanvas.offsetTop+2;
                    x = y/originalH*originalW;
                }
                backgroundCanvas.style.width = x + 'px';
                backgroundCanvas.style.height = y + 'px';
            }

            function stopResizeCanvas() {
                document.removeEventListener('mousemove', resizeCanvas);
                document.removeEventListener('mouseup', stopResizeCanvas);
            }
            
        }
        // 启用内框推拽功能
        var mousedown = null;
        var startMoveDiv = null;
        function enableDraggable2() {
            var backgroundCanvas = document.getElementById('backgroundCanvas');
            var qrcodeCanvas = document.getElementById('qrcodeCanvas');
            var qrcodeCanvasInner = document.getElementById("qrcodeCanvasInner");
            
            var startX, startY, endX, endY,originalW, originalH;
            if(!mousedown){
                mousedown = function(event) {
                    event.stopPropagation();
                    var img = document.querySelector('#qrcodeCanvas img');
                    var qrcodeCanvasInner = document.getElementById("qrcodeCanvasInner");
                    qrcodeCanvasInner.style.cursor = 'nw-resize';
                    startX = event.clientX;
                    startY = event.clientY;
                    originalW = qrcodeCanvas.offsetWidth;
                    originalH = qrcodeCanvas.offsetHeight;
                    document.addEventListener('mousemove', resizeCanvas);
                    document.addEventListener('mouseup', stopResizeCanvas);
                }
            }
            qrcodeCanvas.removeEventListener('mousedown', mousedown);

            qrcodeCanvas.addEventListener('mousedown', mousedown);
            function resizeCanvas(event) {
                var img = document.querySelector('#qrcodeCanvas img');
                // 根据y轴线的变化等比获取x轴线变化值
                endX = event.clientX;
                endY = event.clientY;
                var changeX = endX - startX;
                var changeY = endY - startY;
                var change = Math.max(changeX, changeY);
                // 根据x值的变化来计算y值的变化
                var width = originalW+change;
                console.log(originalW);
                width = width >= backgroundCanvas.offsetWidth ? backgroundCanvas.offsetWidth : width;
                width = width >= backgroundCanvas.offsetHeight ? backgroundCanvas.offsetHeight : width;
                width = width <= 20 ? 20 : width;
                img.style.width = width + 'px';
                img.style.height = width + 'px';
            }

            function stopResizeCanvas() {
                var qrcodeCanvasInner = document.getElementById("qrcodeCanvasInner");
                qrcodeCanvasInner.style.removeProperty('cursor');
                document.removeEventListener('mousemove', resizeCanvas);
                document.removeEventListener('mouseup', stopResizeCanvas);
            }
            if(!startMoveDiv){
                startMoveDiv = function(e){
                    e.stopPropagation();
                    startX = event.clientX;
                    startY = event.clientY;
                    originalW = qrcodeCanvas.offsetLeft;
                    originalH = qrcodeCanvas.offsetTop;
                    document.addEventListener('mousemove', moveDiv);
                    document.addEventListener('mouseup', moveEnd);
                }
            }
            qrcodeCanvasInner.removeEventListener('mousedown', startMoveDiv);
            qrcodeCanvasInner.addEventListener('mousedown',startMoveDiv);

            function moveDiv(event){
                var qrcodeCanvas = document.getElementById('qrcodeCanvas');
                var img = document.querySelector('#qrcodeCanvas img');
                var backgroundCanvas = document.getElementById('backgroundCanvas');

                // 根据y轴线的变化等比获取x轴线变化值
                endX = event.clientX;
                endY = event.clientY;
                changeX = endX - startX;
                changeY = endY - startY;
                let currentPositionX = originalW+changeX;
                let currentPositionY = originalH+changeY;

                // 最右限制和最下限制
                currentPositionX = Math.min(currentPositionX,backgroundCanvas.offsetWidth-img.offsetWidth-2);
                currentPositionY = Math.min(currentPositionY,backgroundCanvas.offsetHeight-img.offsetHeight-2);
                
                // 限制不能超过左边框，不能超过上边框
                currentPositionX = Math.max(currentPositionX,-2);
                currentPositionY = Math.max(currentPositionY,-2);


                qrcodeCanvas.style.left = currentPositionX+'px';
                qrcodeCanvas.style.top = currentPositionY+'px';
            }

            function moveEnd(event){
                document.removeEventListener('mousemove', moveDiv);
                document.removeEventListener('mouseup', moveEnd);
            }
        }
        // 导出图片
        document.getElementById('exportButton').addEventListener('click', function() {
            var oldBackgroundCanvas = document.getElementById('backgroundCanvas');
            //var canvas = document.querySelector('#qrcodeCanvasInner>canvas');
            var oldbgCtx = oldBackgroundCanvas.getContext('2d');
            var backgroundCanvas = document.createElement('canvas');
            backgroundCanvas.width = oldBackgroundCanvas.width;
            backgroundCanvas.height = oldBackgroundCanvas.height;
            // 获取新Canvas的2D渲染上下文
            var bgCtx = backgroundCanvas.getContext('2d');

            // 复制原始Canvas的内容到新的Canvas
            bgCtx.drawImage(oldBackgroundCanvas, 0, 0);

            // 获取canvas内真正用于绘制的像素数据
            var qrImageData = bgCtx.getImageData(0, 0, backgroundCanvas.width, backgroundCanvas.height);
            // 获取长度
            var bgPxWidth = qrImageData.width;
            var bgPxHeight = qrImageData.height;
            // 获取二维码大小
            var qrcodeCanvas = document.getElementById('qrcodeCanvas');
            var qrWidth = qrcodeCanvas.clientWidth;
            var qrHeight = qrcodeCanvas.clientHeight;
            // 获取二维码偏移量
            var left = qrcodeCanvas.offsetLeft + 2;
            var top = qrcodeCanvas.offsetTop + 2;
            // 获取背景图片长度和宽度
            var bgWidth = oldBackgroundCanvas.clientWidth;
            var bgHeight = oldBackgroundCanvas.clientHeight;

            // 获取二维码画布像素
            var qrPxWidth = Math.floor(qrWidth/bgWidth * bgPxWidth);
            // 获取二维码画布一个单位像素
            var qrList = qrcode._oQRCode.modules;
            var oneLength = qrList[0].length;
            var oneQrPx = Math.floor(qrPxWidth / oneLength);
            // 获取左偏移量
            var leftPx = Math.floor(left / bgWidth * bgPxWidth);
            var topPx = Math.floor(top / bgHeight * bgPxHeight);
            window.aaa = qrImageData;
            // 创建模拟数组
            var indexList = [[]];
            var index = 1;
            for(var hang = 0;hang < bgPxHeight;hang++){
                indexList[hang] = [];
                for(var ge = 0;ge < bgPxWidth;ge++){
                    indexList[hang][ge] = index;
                    index++;
                }
            }
            for(var i=0;i<qrList.length;i++){
                var hangQrList = qrList[i];
                for(var k=0;k<hangQrList.length;k++){
                    var isQr = hangQrList[k];
                    var hangStart,hangEnd,lieStart,lieEnd;
                    hangStart = i * oneQrPx + topPx;
                    hangEnd = hangStart+oneQrPx;
                    lieStart = k * oneQrPx + leftPx;
                    lieEnd = lieStart+oneQrPx;
                    for(var hang = hangStart;hang<hangEnd;hang++){
                        for(var lie = lieStart;lie<lieEnd;lie++){
                            var index = indexList[hang][lie];
                            var imgIndex = index * 4;
                            if(isQr){
                                qrImageData.data[imgIndex] = (qrImageData.data[imgIndex] - 105) * 1.7;
                                qrImageData.data[imgIndex + 1] = (qrImageData.data[imgIndex + 1]-105) * 1.7;
                                qrImageData.data[imgIndex + 2] = (qrImageData.data[imgIndex + 2]-105) * 1.7;
                                qrImageData.data[imgIndex + 3] = 255 * 0.6;
                            }
                        }
                    }
                }
            }

            // 将处理过的二维码像素数据绘制到背景canvas对应位置
            bgCtx.putImageData(qrImageData, 0, 0);

            document.querySelector("#show").innerHTML = '';
            document.querySelector("#show").appendChild(backgroundCanvas);
            // 导出最终处理后的背景canvas为图片
            var finalImage = backgroundCanvas.toDataURL('image/png');
            // 这里可以添加保存图片至本地
            var link = document.createElement('a');
            link.href = finalImage;
            link.download = 'qrcode.png';
            link.click();
        });
    </script>
</body>
</html>